# -*- coding:utf-8 -*-

import os
import sys
import mmap
import shutil
from ctypes import Structure, c_uint8, c_char, memmove, addressof, sizeof, string_at


class FileNode(Structure):
    _fields_ = [("addr_m", c_uint8),
                ("addr_h", c_uint8),
                ("name", c_char*10),
                ("size_l", c_uint8),
                ("size_m", c_uint8),
                ("size_h", c_uint8),
                ("type", c_uint8)]


def gam2flash(gam_path):
    flash_path = r'FLASH.DAT'
    flash_size = os.path.getsize(flash_path)
    if flash_size != 0x200000:
        print('flash文件不为2MB，请检查flash文件是否正确')
        return
    gam_size = os.path.getsize(gam_path)
    databag_num = (gam_size+0xFFF)>>12
    print(f'{os.path.basename(gam_path)}文件大小：{gam_size}，需要{databag_num}个扇区来保存')
    f = open(gam_path, 'rb')
    gam_data = f.read()
    f.close()
    file_node = FileNode()
    file_node.name = gam_data[6:16]
    file_node.size_l = gam_size
    file_node.size_m = gam_size >> 8
    file_node.size_h = gam_size >> 16
    file_node.type = 0x3d
    f = open(flash_path, 'r+b')
    mm = mmap.mmap(f.fileno(), 0)
    free_sector = 0
    for index in range(0x2000):  # 2MB对应512个扇区
        if mm[0x1000+index] == 0xFF:
            free_sector += 1
            if free_sector == databag_num:
                free_start_addr = (index-(databag_num-1))<<4
                file_node.addr_h = free_start_addr>>8
                file_node.addr_m = free_start_addr&0xFF
                for i in range(databag_num):
                    mm[0x1000+index-(databag_num-i-1)] = 0x01
                break
        else:
            free_sector = 0
    free_node_addr = 0x0000
    while True:
        if mm[free_node_addr+0x0F] in (0x00, 0xFF):
            break
        free_node_addr += 0x10
    mm.seek(free_node_addr)
    mm.write(string_at(addressof(file_node), sizeof(FileNode)))
    mm.seek(free_start_addr<<8)
    mm.write(gam_data)
    mm.close()
    print('end')

if __name__ == '__main__':
    for path in sys.argv[1:]:
        gam2flash(path)